package com.icebartech.core.components;

import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.icebartech.core.conf.AliyunProperties;
import com.icebartech.core.conf.SiteProperties;
import com.icebartech.core.constants.IcebartechConstants;
import java.io.ByteArrayInputStream;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 阿里云oss操作组件类
 * @author wenhsh
 *
 */
@Component
@Slf4j
public class AliyunOSSComponent {
    
    @Autowired
    private AliyunProperties aliyunProperties;
    
    @Autowired
    private RedisComponent redisComponent;
    
    @Autowired
    private SiteProperties siteProperties;
    
    
    private OSSClient getClient() {
        return new OSSClient(aliyunProperties.getOssEndpoint(), aliyunProperties.getAccessId(), aliyunProperties.getAccessKey());
    }
    
    private void closeClient(OSSClient client) {
        if (null != client)
            client.shutdown();
    }
    
    /**
     * 获取一个全局统一的文件id
     * @return
     */
    public String getFileId() {
        String fileId = redisComponent.incRedisKey(IcebartechConstants.ALIYUN_OSS_FILE_GLOBAL_ID_KEY, "GlobalFile").toString();
        return fileId;
    }
    
    
    /**
     * 上传文件到aliyun oss
     * @param fileBytes 文件二进制
     * @return
     */
    public String uploadFile(byte[] fileBytes, String suffix, String fileName) {
        String fileKey = siteProperties.getAppName() + "/" + getFileId() + "." + suffix;
        
        ByteArrayInputStream in = new ByteArrayInputStream(fileBytes);
        
        OSSClient client = getClient();
        try {
            fileName = StringUtils.isEmpty(fileName) ? fileKey : fileName;
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentDisposition("attachment; filename=\"" + fileName + "\"");
            PutObjectResult result = client.putObject(aliyunProperties.getBucketName(), fileKey, in, metadata);
            String          eTag   = result.getETag();
            log.info("uploadFile fileKey:{}, return etag:{}", new Object[]{fileKey, eTag});
            return StringUtils.isEmpty(eTag) ? null : fileKey;
        } finally {
            closeClient(client);
        }
    }
    
    /**
     * 组装文件url
     * @param fileKey
     * @return
     */
    public String getFileUrl(String fileKey) {
        String url = "";
        if (StringUtils.isNotEmpty(fileKey)) {
            url = aliyunProperties.getOssUrl();
            url = url + (url.endsWith("/") ? "" : "/") + fileKey;
        }
        return url;
    }
    
    
    /**
     * 生成带签名的文件上传链接 只能用PUT方式上传 不支持小程序
     * @param suffix
     * @return
     */
    public Map<String, String> generateUploadUrl(String suffix, String contentType) {
        Map<String, String> rtnMap = new HashMap<>();
        
        String    fileKey = siteProperties.getAppName() + "/" + getFileId() + "." + suffix;
        OSSClient client  = getClient();
        try {
            Date expirationTime = DateUtils.addMinutes(new Date(), 30);
            System.out.println(expirationTime.getTime());
            GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(aliyunProperties.getBucketName(), fileKey);
            //设置过期时间
            generatePresignedUrlRequest.setExpiration(expirationTime);
            //设置Content-Type
            generatePresignedUrlRequest.setContentType(contentType);
            generatePresignedUrlRequest.setMethod(HttpMethod.PUT);
            URL url = client.generatePresignedUrl(generatePresignedUrlRequest);
            rtnMap.put("fileKey", fileKey);
            rtnMap.put("uploadUrl", url.toString().replace("http://", "https://"));
            rtnMap.put("downloadUrl", getFileUrl(fileKey));
            return rtnMap;
        } finally {
            closeClient(client);
        }
    }
    
    /**
     * 生成带签名的文件下载链接
     * @param fileKey
     * @return
     */
    public String generateDownloadUrl(String fileKey) {
        OSSClient client = getClient();
        try {
            Date expirationTime = DateUtils.addMinutes(new Date(), 30);
            URL  url            = client.generatePresignedUrl(aliyunProperties.getBucketName(), fileKey, expirationTime, HttpMethod.GET);
            return getFileUrl(fileKey)+ url.getFile();
        } finally {
            closeClient(client);
        }
    }
}
